<template>
  <div class="comp-side-graph-panel" @click.stop="handleClick">
    <a-tabs
      class="comp-side-graph-panel-tabs"
      size="small"
      :animated="false"
      default-active-key="systemComponent"
      @change="onTabChange"
    >
      <a-tab-pane key="myComponent" tab="我的组件" class="my-component">
        <div v-if="!myComponentLoadedFlag" class="spin-box">
          <a-spin class="spin"></a-spin>
        </div>
        <div v-else>
          <div class="my-component-list">
            <div class="search-box">
              <a-input
                v-model="myComponentSearchWords"
                placeholder="搜索内容"
                @change="onMySearchWordsChange"
              />
            </div>
            <a-collapse
              v-model="myComponentCollapseActiveKeys.total"
              expand-icon-position="left"
              @change="onMyCollapseChange"
            >
              <a-collapse-panel
                v-for="widgetMenuKey in Object.keys(myComponentTargetWidget)"
                :key="widgetMenuKey"
              >
                <template slot="header">
                  <div
                    class="my-component-list-title my-component-list-header-title"
                  >
                    {{ widgetMenuKey === 'dataset' ? '数据集' : 'Pipeline' }}
                  </div>
                </template>
                <div
                  v-if="myComponentTargetWidget[widgetMenuKey].length === 0"
                  class="empty-info"
                >
                  暂无组件
                </div>
                <div v-else class="widget-menu-item-div">
                  <a-collapse
                    v-model="myComponentCollapseActiveKeys[widgetMenuKey]"
                    expand-icon-position="left"
                  >
                    <a-collapse-panel
                      v-for="(taskWidget, taskIndex) in myComponentTargetWidget[
                        widgetMenuKey
                      ]"
                      :key="`${taskWidget.taskName}-${taskIndex}`"
                    >
                      <template slot="header">
                        <div class="my-component-list-title">
                          {{ taskWidget.taskName }}
                        </div>
                      </template>
                      <div class="widget-item-list-div">
                        <a-list
                          :grid="{ column: 2, gutter: 10 }"
                          :data-source="taskWidget.widgets"
                        >
                          <a-list-item
                            slot="renderItem"
                            slot-scope="widget, widgetIndex"
                          >
                            <div
                              :key="`${widget.type}-${widget.tid}-${widgetIndex}`"
                              class="widget-item-div"
                              style="position: relative;"
                              draggable="true"
                              @mousedown.stop="onMyMouseDown"
                              @dragstart="
                                (event) => {
                                  onMyDragstart(event, widget, widgetMenuKey)
                                }
                              "
                            >
                              <img
                                alt=""
                                :src="`${publicPath}${widget.imgSrc}`"
                                :style="{ height: '100%', width: '100%' }"
                              />
                              <div
                                class="hover-visible"
                                style="
                                  background-color: rgba(127, 127, 127, 0.5);
                                  bottom: 0;
                                  left: 0;
                                  position: absolute;
                                  right: 0;
                                  top: 0;
                                "
                              >
                                <div
                                  style="
                                    color: #fff;
                                    overflow: hidden;
                                    padding: 5px;
                                    position: relative;
                                    text-align: center;
                                    text-overflow: ellipsis;
                                    top: 12px;
                                    white-space: nowrap;
                                  "
                                >
                                  {{ widget.name }}
                                </div>
                                <!--删除icon-->
                                <div
                                  v-if="widget.id !== null"
                                  style="
                                    color: #fff;
                                    font-size: 13px;
                                    position: absolute;
                                    right: 3px;
                                    top: 0.5px;
                                  "
                                >
                                  <a-tooltip placement="top">
                                    <template slot="title">
                                      <span>删除</span>
                                    </template>
                                    <a-icon-font
                                      type="iconicon-beifen5-copy"
                                      class="little-icon"
                                      @click="onDelete(widget)"
                                    />
                                  </a-tooltip>
                                </div>
                                <!--编辑icon-->
                                <div
                                  v-if="widget.id !== null"
                                  style="
                                    color: #fff;
                                    font-size: 14px;
                                    position: absolute;
                                    right: 20px;
                                    top: 0;
                                  "
                                >
                                  <a-tooltip placement="top">
                                    <template slot="title">
                                      <span>编辑</span>
                                    </template>
                                    <a-icon-font
                                      type="iconicon-beifen6-copy"
                                      class="little-icon"
                                      @click="
                                        editMyVisualization(
                                          widget,
                                          widgetMenuKey
                                        )
                                      "
                                    />
                                  </a-tooltip>
                                </div>
                              </div>
                            </div>
                          </a-list-item>
                        </a-list>
                        <div
                          class="widget-item-list-add-btn"
                          @click="addMyVisualization(taskWidget, widgetMenuKey)"
                        >
                          <div></div>
                          <a-icon type="plus-circle" />
                          <span>
                            添加可视化
                          </span>
                        </div>
                      </div>
                    </a-collapse-panel>
                  </a-collapse>
                </div>
              </a-collapse-panel>
            </a-collapse>
          </div>
        </div>
      </a-tab-pane>
      <a-tab-pane key="systemComponent" tab="系统组件">
        <div class="search-box">
          <a-input
            v-model="systemComponentSearchWords"
            placeholder="搜索内容"
          />
        </div>
        <div class="tab-box">
          <a-tabs
            v-if="systemComponentSearchWords === ''"
            tab-position="left"
            @change="onSystemSelectedTypeChange"
          >
            <a-tab-pane v-for="item in (Object.keys(chartTypes))" :key="item">
              <span slot="tab">
                <a-tooltip placement="left">
                  <template slot="title">
                    <span>{{ chartTypes[item].title }}</span>
                  </template>
                  <img
                    v-if="chartTypes[item].active"
                    :class="
                      chartTypes[item].iconClass
                        ? chartTypes[item].iconClass
                        : ''
                    "
                    draggable="false"
                    :src="
                      publicPath + chartTypes[item].iconCharCode + '-active.svg'
                    "
                    alt=""
                    :style="{ width: '22px' }"
                  />
                  <img
                    v-else
                    :class="
                      chartTypes[item].iconClass
                        ? chartTypes[item].iconClass
                        : ''
                    "
                    draggable="false"
                    :src="publicPath + chartTypes[item].iconCharCode + '.svg'"
                    alt=""
                    :style="{ width: '22px' }"
                  />
                </a-tooltip>
              </span>
              <div>
                <div
                  v-for="(chartItem, j) in systemComponents"
                  :key="`chart-${j}`"
                  class="chart-item"
                  draggable="true"
                  @mousedown.stop="onSystemMouseDown"
                  @dragstart="
                    (event) => {
                      onSystemDragstart(event, item, chartItem.name)
                    }
                  "
                >
                  <card size="small" style="pointer-events: none;">
                    <span
                      slot="title"
                      :style="{ 'font-weight': 600, color: '#5d637e' }"
                    >
                      {{ chartItem.title }}
                    </span>
                    <img
                      alt=""
                      :src="`${publicPath}${chartItem.imgSrc}`"
                      :style="{ height: '100%', width: '100%' }"
                    />
                  </card>
                </div>
              </div>
            </a-tab-pane>
          </a-tabs>
          <div v-else>
            <div>
              <div
                v-for="(chartItem, j) in systemComponents"
                :key="`chart-${j}`"
                class="chart-item-search"
                draggable="true"
                @mousedown.stop="onSystemMouseDown"
                @dragstart="
                  (event) => {
                    onSystemDragstart(
                      event,
                      chartItem.chartType,
                      chartItem.name
                    )
                  }
                "
              >
                <card size="small" style="pointer-events: none;">
                  <span
                    slot="title"
                    :style="{ 'font-weight': 600, color: '#5d637e' }"
                  >
                    {{ chartItem.title }}
                  </span>
                  <img
                    alt=""
                    :src="`${publicPath}${chartItem.imgSrc}`"
                    :style="{ height: '100%', width: '100%' }"
                  />
                </card>
              </div>
            </div>
          </div>
        </div>
      </a-tab-pane>
    </a-tabs>
    <modal-visualization
      :chart-config="myModalVisualizationConfig.chartConfig"
      :dataset-list="myModalVisualizationConfig.datasetList"
      :visible="myModalVisualizationConfig.visible"
      @cancel="myModalVisualizationConfig.visible = false"
      @ok="onSave"
    >
    </modal-visualization>
  </div>
</template>
<script lang="ts">
import { Card } from 'ant-design-vue'
import { Vue, Component } from 'vue-property-decorator'
import { chartMaps, chartTypes, GEOMAP_NAME } from '@/config/contant'
import {
  widgetQueryByProject,
  deleteWidget,
  saveWidget,
  updateWidget,
} from '@/api/widget'
import ModalVisualization from '@/components/common/VisualizationDashboard/ModalVisualization.vue'
import Chart from '@/components/chart/chart.vue'

import { isArray } from '@/util/data-view-table-helper'
import VisualizationStore from '@/store/modules/visualization'
import DataViewStore from '@/store/modules/dataview'
import { Widget } from '@/util/chart-widget'
import { publicPath } from '@/api/constants'

@Component({
  components: {
    Card,
    Chart,
    ModalVisualization,
  },
})
export default class SideGraphPanel extends Vue {
  private mouseDownPos: any = {
    x: 0,
    y: 0,
  }
  systemComponentSearchWords: string = ''
  systemComponentSelectedType: string = 'barChart'
  private chartMaps: any = chartMaps
  private chartTypes: any = chartTypes
  private tabsActiveKey: string = 'systemComponent'

  private publicPath = publicPath // 基础URL

  myComponentLoadedFlag: boolean = false
  myComponentWidget: { dataset: Array<any>; pipeline: Array<any> } = {
    dataset: [],
    pipeline: [],
  } // 原始的层次化的 dataset/pipeline->tasks->widgets
  myComponentWidgetList: Array<any> = [] // 摊平的widgets 存到VisualizationStore
  myComponentSearchWords: string = ''
  myComponentWidgetSearchResult: {
    dataset: Array<any>
    pipeline: Array<any>
  } = {
    dataset: [],
    pipeline: [],
  }
  // 缓存collapse展开状态
  myComponentCollapseActiveKeys: any = {
    total: ['dataset', 'pipeline'],
    dataset: [],
    pipeline: [],
  }
  myComponentCollapseActiveKeysCache: any = null

  myModalVisualizationConfig: {
    visible: boolean
    chartConfig: any
    datasetList: {
      dataset: Array<any>
      pipeline: Array<any>
    }
    widgetId?: number
  } = {
    visible: false,
    chartConfig: {},
    datasetList: {
      dataset: [],
      pipeline: [],
    },
  }

  public get systemComponents() {
    const result: any[] = []
    const keywords = this.systemComponentSearchWords.trim()
    Object.values(this.chartMaps).forEach((key: any) => {
      key.forEach((k: any) => {
        if (
          (keywords === '' &&
            k.chartType === this.systemComponentSelectedType) ||
          (keywords !== '' &&
            (k.title.includes(keywords) ||
              k.name.toLowerCase().includes(keywords.toLowerCase())))
        ) {
          result.push(k)
        }
      })
    })
    return result
  }

  get myComponentTargetWidget() {
    return this.myComponentSearchWords.trim()
      ? this.myComponentWidgetSearchResult
      : this.myComponentWidget
  }

  /**
   * pipeline 状态
   */
  private get pipelineStatus(): string[] {
    const nodeStatus = DataViewStore.pipelineNodes
      ?.filter((item: any) => item.type !== 3)
      ?.map((d: any) => d?.data?.lastStatus)

    return nodeStatus || []
  }

  // @Watch('pipelineStatus')
  // private onPipelineStatusChange(newValue: any, oldValue: any) {
  //   if (isEqual(newValue, oldValue)) {
  //     return
  //   }
  //   if (
  //     this.tabsActiveKey === 'myComponent' &&
  //     !this.pipelineStatus.includes('RUNNING')
  //   ) {
  //     this.myComponentLoadedFlag = false
  //     this.onTabChange('myComponent')
  //   }
  // }

  public handleClick() {
    VisualizationStore.changePreviewPopStatus('close')
  }

  mounted() {
    Object.keys(chartTypes).forEach((chartType: string) => {
      chartTypes[chartType].active = false
    })
    chartTypes.barChart.active = true
  }

  onSystemMouseDown(event: any) {
    this.mouseDownPos.x = event.layerX - 6
    this.mouseDownPos.y = event.layerY - event.target.offsetTop
    // 这里用来把offset 先存储起来，方便drop时定位
    VisualizationStore.setDraggingOffset(this.mouseDownPos)
  }
  // 拖拽组件
  onSystemDragstart(event: any, chartType: string, chartSubType: string) {
    event.dataTransfer.setData('text', `${chartType}|${chartSubType}`)
  }
  // 切换系统组件中的ChartType
  onSystemSelectedTypeChange(item: any) {
    this.systemComponentSelectedType = item
    Object.keys(chartTypes).forEach((key) => {
      chartTypes[key].active = key === item
    })
  }

  /** 检测数据是否为graph数据 */
  checkIsGraphData(itemData: any): boolean {
    return (
      itemData &&
      itemData.data &&
      isArray(itemData.data.nodes) &&
      isArray(itemData.data.links)
    )
  }

  /** 判断是否为地图组件 */
  checkIsGeoMapData(item: any) {
    return (
      item &&
      item.data &&
      isArray(item.data.chartType) &&
      (item.data.chartType as Array<string>).includes(GEOMAP_NAME)
    )
  }

  async onDelete(widget: Widget) {
    const responseData = await this.deleteWidget(widget)
    if (responseData.code === 100) {
      this.myComponentLoadedFlag = false
      //  init para
      this.myComponentWidget = {
        dataset: [],
        pipeline: [],
      }
      this.myComponentWidgetList = []
      this.onTabChange('myComponent')
      this.$message.success('删除可视化成功')
    } else {
      this.$message.error('删除可视化失败')
    }
  }

  async deleteWidget(widget: Widget) {
    const response = await deleteWidget({
      data: {
        id: widget.id,
        projectId: localStorage.getItem('projectId'),
        type: 'task',
      },
    })
    return response.data
  }

  async onSave(widget: Widget) {
    const responseData =
      this.myModalVisualizationConfig.widgetId === undefined
        ? await this.saveWidget(widget)
        : await this.updateWidget(widget)
    if (responseData.code === 100) {
      this.myComponentLoadedFlag = false
      //  init para
      this.myComponentWidget = {
        dataset: [],
        pipeline: [],
      }
      this.myComponentWidgetList = []
      this.myModalVisualizationConfig = {
        visible: false,
        chartConfig: {},
        datasetList: {
          dataset: [],
          pipeline: [],
        },
        widgetId: undefined,
      }
      this.onTabChange('myComponent')
      this.$message.success('保存可视化成功')
    } else {
      this.$message.error('保存可视化失败')
    }
  }

  async saveWidget(widget: Widget) {
    const parameters = {
      data: {
        dashboardId: -1,
        data: widget.data,
        name: widget.name,
        randomId: Math.floor(Math.random() * 10000),
        tid: widget.tid,
        type: widget.type,
        projectId: localStorage.getItem('projectId'),
      },
    }
    const response = await saveWidget(parameters)
    return response.data
  }

  async updateWidget(widget: Widget) {
    const parameters = {
      data: {
        dashboardId: -1,
        data: widget.data,
        id: this.myModalVisualizationConfig.widgetId,
        name: widget.name,
        type: widget.type,
        projectId: localStorage.getItem('projectId'),
      },
    }
    const response = await updateWidget(parameters)
    return response.data
  }

  onMyMouseDown(event: any) {
    this.mouseDownPos.x = event.layerX - 6
    this.mouseDownPos.y = event.layerY
    // 这里用来把offset 先存储起来，方便drop时定位
    VisualizationStore.setDraggingOffset(this.mouseDownPos)
  }
  onMyDragstart(
    event: any,
    widget: any,
    widgetMenuKey: 'dataset' | 'pipeline'
  ) {
    const { chartType = [] } = widget
    event.dataTransfer.setData(
      'text',
      `${widget.id}$${widget.tid}$${
        widget.type
      }$${widgetMenuKey}$${chartType.join('|')}`
    )
  }

  parseMyComponentWidget(widgetResults: any) {
    // const keys = ['dataset']
    // // pipeline运行状态下不能显示pipeline目录
    // if (!this.pipelineStatus.includes('RUNNING')) {
    //   keys.push('pipeline')
    // }
    ;['dataset', 'pipeline'].forEach((keyName, keyIndex) => {
      // @ts-ignore
      this.myComponentWidget[keyName] = widgetResults[keyIndex].taskWidgets
        .map((task: any) => {
          return {
            ...task,
            widgets: task.widgets.map((widget: any) => {
              // console.log('###',task,widget)
              if (
                !this.myComponentWidgetList.some((w: any) => {
                  return (
                    w.id === widget.id &&
                    w.tid === widget.tid &&
                    w.type === widget.type
                  )
                })
              ) {
                this.myComponentWidgetList.push({
                  ...widget,
                  pipelineId: widgetResults[keyIndex].pipelineId,
                })
              }

              let chartType: Array<string> = ['table', 'table']
              if (widget.data.chartType) {
                chartType = [...widget.data.chartType]
              } else if (widget.type === 'configuration') {
                chartType = ['configuration', 'configuration']
              }

              const imgSource = this.chartMaps[chartType[0]]?.filter(
                (chartConfig: any) => chartConfig.name === chartType[1]
              )[0]?.imgSrc
              return {
                ...widget,
                chartType,
                imgSrc: imgSource,
                taskName: task.taskName,
              }
            }),
          }
        })
        .filter((task: any) => {
          return (
            task.widgets.length > 0 &&
            !(
              keyName === 'pipeline' &&
              task.widgets.find((widget: any) => widget.id === null)?.type ===
                null
            )
          )
        })
    })

    VisualizationStore.updatePipelineWidgetList(this.myComponentWidgetList)
  }

  /**
   * 搜索pipeline及其下面的图表
   */
  onMySearchWordsChange() {
    const keywords = this.myComponentSearchWords.trim()
    if (!keywords) {
      // 还原无SearchWords时的展开状态
      this.myComponentCollapseActiveKeys = this.myComponentCollapseActiveKeysCache
      this.myComponentCollapseActiveKeysCache = null
      return
    }
    if (this.myComponentCollapseActiveKeysCache === null) {
      // 保存无SearchWords时的展开状态
      this.myComponentCollapseActiveKeysCache = this.myComponentCollapseActiveKeys
      this.myComponentCollapseActiveKeys = {
        total: ['dataset', 'pipeline'],
        dataset: [],
        pipeline: [],
      }
    }
    const result: { dataset: Array<any>; pipeline: Array<any> } = {
      dataset: [],
      pipeline: [],
    }
    Object.keys(result).forEach((typeKey: string) => {
      // @ts-ignore
      this.myComponentWidget[typeKey].forEach((taskWidgets: any) => {
        if (taskWidgets.taskName.includes(keywords)) {
          // pipeline名字包含关键字，则pipeline下全部图表都加入
          // @ts-ignore
          result[typeKey].push(taskWidgets)
        } else {
          const widgets = taskWidgets.widgets.filter((widget: any) =>
            widget.name.includes(keywords)
          )
          if (widgets.length > 0) {
            // @ts-ignore
            result[typeKey].push({
              ...taskWidgets,
              widgets,
            })
          }
        }
      })
    })
    this.myComponentWidgetSearchResult = result
  }

  onMyCollapseChange() {
    ;['dataset', 'pipeline']
      .filter((k) => !this.myComponentCollapseActiveKeys.total.includes(k))
      .forEach((k) => {
        this.myComponentCollapseActiveKeys[k] = []
      })
  }

  onTabChange(activeKey: string) {
    this.tabsActiveKey = activeKey
    if (activeKey === 'myComponent' && !this.myComponentLoadedFlag) {
      this.myComponentLoadedFlag = true
      const projectId = this.$route.params.id
      widgetQueryByProject({
        data: {
          projectId,
        },
      })
        .then((response) => {
          this.parseMyComponentWidget(response.data.result)
        })
        .catch(() => {
          this.myComponentLoadedFlag = false
        })
    }
  }

  addMyVisualization(taskWidget: any, widgetType: 'dataset' | 'pipeline') {
    const widget = taskWidget.widgets.find((w: any) => {
      return w.id === null
    })
    if (widget) {
      const datasetList: any = {
        dataset: [],
        pipeline: [],
      }
      datasetList[widgetType].push({
        id: widget.tid,
        name: widget.taskName,
        tableName: widget.data.table,
      })
      this.myModalVisualizationConfig = {
        chartConfig: {
          widgetType,
          chartOptions: {
            dataId: widget.tid,
            dataType: widget.type === 'configuration' ? 'task' : widget.type,
          },
        },
        datasetList,
        visible: true,
        widgetId: undefined,
      }
    }
  }

  editMyVisualization(widget: any, widgetType: 'dataset' | 'pipeline') {
    const datasetList: any = {
      dataset: [],
      pipeline: [],
    }
    datasetList[widgetType].push({
      id: widget.tid,
      name: widget.taskName,
      tableName: widget.data.table,
    })
    this.myModalVisualizationConfig = {
      chartConfig: {
        ...widget.data,
        widgetJson: {
          ...widget.data.widgetJson,
        },
        widgetType,
      },
      datasetList,
      visible: true,
      widgetId: widget.id,
    }
  }
}
</script>
<style lang="less" scoped>
.comp-side-graph-panel {
  background: #fff;
  border-right: 1px solid #e9e9e9;
  height: 100%;
  user-select: none;
  width: 230px;

  /deep/ .ant-tabs-tabpane-active {
    height: 100%;
  }

  /deep/ .ant-tabs-tabpane-inactive {
    height: 0;
  }

  /deep/ .ant-tabs.comp-side-graph-panel-tabs {
    height: 100%;

    > .ant-tabs-bar .ant-tabs-nav {
      height: 39px;
      letter-spacing: 1px;

      // tab标题
      .ant-tabs-tab {
        color: #222432;
        font-weight: 500;
        opacity: 0.5;

        &.ant-tabs-tab-active {
          color: #222432;
          font-weight: 600;
          opacity: 1;
        }
      }
    }

    .ant-tabs-content {
      height: 100%;
    }

    .spin-box {
      height: auto;
      width: 220px;
    }

    .spin {
      display: block;
      margin: 48px auto;
    }
  }

  /deep/ .ant-tabs-top-bar {
    margin: 0;
  }

  .search-box {
    box-sizing: border-box;
    padding: 10px;
    width: 100%;

    /deep/ .ant-input {
      border-radius: 16px;
    }
  }

  .tab-box {
    background: #f9f9fc;
    height: calc(100% - 95px);
    overflow-x: hidden;
    overflow-y: scroll;
    transition: all ease 0.2s;
    width: 100%;

    &::-webkit-scrollbar {
      height: 6px;
      width: 6px;
    }

    &::-webkit-scrollbar-thumb {
      background: rgba(144, 147, 153, 0.5);
      border-radius: 6px;
    }

    &::-webkit-scrollbar-track {
      background: transparent;
      border-radius: 5px;
    }

    /deep/ .ant-tabs {
      // height: 100%; // 设置height会有回弹动画
      min-height: 100%;

      .ant-tabs-tab span {
        font-size: 24px;
        margin-left: -11px;
      }
    }

    /deep/ .ant-tabs-nav-wrap {
      background: #fff;
      height: 100%;
    }

    /deep/ .ant-tabs-tab {
      border: 1px solid transparent;
      margin: 0;
      width: 40px;

      &.ant-tabs-tab-active {
        background: #f0f3ff !important;
      }

      &:hover {
        background-color: #f9f9fc;
      }
    }

    /deep/ .ant-tabs .ant-tabs-left-bar {
      .ant-tabs-ink-bar {
        display: none !important;
      }
    }

    /deep/ .ant-tabs .ant-tabs-left-content {
      padding-left: 0;
    }

    /deep/ .ant-card {
      border-width: 0;
      text-align: left;

      .ant-card-body {
        padding: 0;
      }

      .ant-card-head {
        background-color: #f6f8ff;
        border-bottom-width: 0;
      }
    }
  }

  .chart-item {
    background: #fff;
    border: 1px solid #e9e9eb;
    border-radius: 4px;
    cursor: pointer;
    height: 122px;
    line-height: 108px;
    margin-left: 5px;
    text-align: center;
    width: 170px;

    &:hover {
      border: 1px solid #dfe1fd;
    }
  }

  .chart-item-search {
    background: #fff;
    border: 1px solid #e9e9eb;
    border-radius: 4px;
    cursor: pointer;
    height: 142px;
    line-height: 108px;
    margin-bottom: 5px;
    margin-left: 5px;
    text-align: center;
    width: calc(100% - 10px);

    &:hover {
      border: 1px solid #dfe1fd;
    }
  }

  .chart-item + .chart-item {
    margin-top: 10px;
  }

  .my-component {
    overflow-y: auto;
    padding-bottom: 30px;

    &::-webkit-scrollbar {
      height: 6px;
      width: 6px;
    }

    &::-webkit-scrollbar-thumb {
      background: rgba(144, 147, 153, 0.5);
      border-radius: 6px;
    }

    &::-webkit-scrollbar-track {
      background: transparent;
      border-radius: 5px;
    }

    /deep/ .ant-collapse-content-box {
      padding: 0;
    }

    /deep/ .ant-collapse > .ant-collapse-item,
    /deep/ .ant-collapse-content {
      border: 0;
    }

    /deep/ .ant-collapse {
      background-color: #fff;
      border: 0;
      margin-top: 10px;

      &.ant-collapse-icon-position-left .ant-collapse-header {
        padding-left: 30px;

        .ant-collapse-arrow {
          font-size: 8px;
        }
      }

      .widget-menu-item-div {
        .ant-collapse {
          margin-top: 0;
        }

        .ant-collapse-header {
          margin-left: 20px;
        }

        .widget-item-list-div {
          background-color: #f9f9fc;
          position: relative;

          .ant-list {
            max-height: 212px;
            overflow-y: auto;
            padding: 10px 10px 28px;

            &::-webkit-scrollbar {
              width: 2px;
            }

            &::-webkit-scrollbar-thumb {
              // background: #c7c9cc;
              background: transparent;
              border-radius: 2px;
            }

            &:hover::-webkit-scrollbar-thumb {
              background: #c7c9cc;
            }
          }

          .widget-item-list-add-btn {
            border-width: 0;
            bottom: 0;
            height: 28px;
            left: 0;
            line-height: 28px;
            position: absolute;
            right: 0;
            text-align: center;

            div {
              background: #6771fc;
              height: 100%;
              left: 0;
              opacity: 0.1;
              position: absolute;
              top: 0;
              width: 100%;
            }

            i {
              color: #222432;
              opacity: 0.5;
            }

            span {
              color: #222432;
              font-size: 12px;
              font-weight: 400;
              letter-spacing: 1.12px;
              opacity: 0.5;
            }

            &:hover {
              cursor: pointer;

              span,
              i {
                color: #6973ff;
                opacity: 1;
              }
            }
          }
        }

        .widget-item-div {
          border-radius: 2px;
          box-shadow: 0 0 4px 0 rgba(88, 98, 230, 0.2);
        }

        .ant-list-item {
          background-color: #fff;
          margin-bottom: 10px;
        }
      }
    }

    /deep/ .ant-collapse-header {
      padding: 9px 16px;
    }

    .empty-info {
      height: 40px;
      line-height: 40px;
      text-align: center;
    }

    .chart-box {
      border: 1px solid #e9e9eb;
      border-radius: 4px;
      cursor: pointer;
      height: 220px;
      margin: 10px auto 0;
      overflow: hidden;
      position: relative;
      width: 210px;

      .chart-title {
        background-color: #f9faff;
        color: rgb(93, 99, 126);
        font-size: 14px;
        font-weight: 600;
        height: 30px;
        line-height: 30px;
        padding: 0 12px;

        .delete-button {
          float: right;
        }
      }

      .chart-box-real {
        height: 220px !important;
        pointer-events: none;
        position: relative;
        width: 208px !important;
      }

      .mask {
        background: transparent;
        bottom: 0;
        cursor: pointer;
        height: calc(100% - 30px);
        left: 0;
        position: absolute;
        width: 100%;
        z-index: 310;
      }
    }

    .my-component-list-title {
      color: #5d637e;
      font-weight: 400;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      width: 100%;

      &.my-component-list-header-title {
        font-weight: 600;
      }
    }

    .hover-visible {
      visibility: hidden;
    }

    .widget-item-div:hover > .hover-visible {
      visibility: visible;
    }
  }

  .icon-map {
    transform: scale(1.2);
  }
}

.bottom-spinning {
  width: 100%;
}
</style>
